package net.midnighttd.game.entity;

import net.midnighttd.engine.view.sprite.*;
import net.midnighttd.engine.Engine;
import net.midnighttd.engine.entity.Entity;
import net.midnighttd.engine.entity.Pathfinder.MapNode;
import net.midnighttd.engine.entity.Pathfinder.PathFoundListener;
import net.midnighttd.engine.entity.Pathfinder.Path;
import net.midnighttd.engine.CollisionStateListener;
import net.midnighttd.game.sprite.HPBar;
import org.w3c.dom.Element;

import java.awt.*;

/**
 * Author: Adam Scarr
 * Date: 19/04/2009
 * Time: 7:21:57 PM
 *
 * Basis for all moving entitys.
 */
public class Unit extends Entity implements MovementStateListener, CollisionStateListener, PathFoundListener {
    private int maxHp;
    private int hp;
    private int speed;
    private int destX, destY;
    private int bounty;
    private boolean flying;
    private boolean recalc = false;
    private HPBar hpbar;

    public Unit(Unit unit) {
        super(unit);
        speed = unit.speed;
        maxHp = unit.maxHp;
        hp = unit.hp;
        bounty = unit.bounty;
        flying = unit.flying;
        hpbar = (HPBar)unit.hpbar.copy();
        sprite.addChild(hpbar);
        sprite.addMovementStateListener(this);
        engine.getEntityManager().addCollisionStateListener(this);
    }

    public Unit(Engine game, SpriteManager sm, Element element) {
        super(game, sm, element);
        maxHp = Integer.valueOf(element.getAttribute("hp"));
        speed = Integer.valueOf(element.getAttribute("speed"));
        bounty = Integer.valueOf(element.getAttribute("bounty"));
        flying = element.getAttribute("flying").equals("yes");
        hp = maxHp;
        hpbar = new HPBar(sprite.getWidth());
        sprite.addChild(hpbar);
        type = "unit";
        sprite.addMovementStateListener(this);
        game.getEntityManager().addCollisionStateListener(this);
    }

    public void moveTo(int x, int y) {
        destX = x;
        destY = y;
        engine.getEntityManager().getPathfinder().search(this.getX(), this.getY(), x, y, flying, this);
    }

    public void drawEntity(Graphics g) {
       
    }

     public void movementStateChanged(Sprite sprite, MovementState state, Movement movement) {
        if(this.sprite == sprite) {
            if(state == MovementState.end) {
                setLocation(movement.getFinalX() / 24, movement.getFinalY() / 24);
            }
        }
    }

    public double getRotation(int oldX, int oldY, int newX, int newY) {
        int dx = newX - oldX;
        int dy = newY - oldY;
        if(dx > 0) {
            return 0;
        } else if(dx < 0){
            return Math.PI;
        }

        if(dy > 0) {
            return Math.PI / 2;
        } else if(dy < 0){
            return Math.PI * 1.5;
        }

        return 0;
    }

    public double getHpPercent() {
        return hp/(double)maxHp;
    }

    public int getMaxHp() {
        return maxHp;
    }

    public int getHp() {
        return hp;
    }

    public Entity getDuplicate() {
        return new Unit(this);
    }

    public void CollisionStateChanged() {
        if(!flying) {
            recalc = true;
            moveTo(destX, destY);
        }
    }

    public void takesDamage(int damage) {
        hp -= damage;
        hpbar.setFullness(getHpPercent());
        if(hp <= 0) {
            setActive(false);
            engine.getEntityManager().removeActiveEnt(this);
        }
    }

    public boolean isDead() {
        return hp < 0;
    }

    public int getBounty() {
        return bounty;
    }

    public void pathFound(Path path) {
        if(recalc) {
            sprite.stop();
            recalc = false;
        }

        if(path != null) {
            MapNode last = path.poll();
            for(MapNode node: path) {
                sprite.rotateTo(getRotation(last.getX(), last.getY(), node.getX(), node.getY()), 10);
                sprite.moveTo(node.getX() * 24, node.getY() * 24, speed * 24);
                last = node;
            }
        }
    }
}
